
package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import AnaliseLexicaFinal.EstruturaDeDados.Token;
import java.util.ArrayList;
import java.util.LinkedList;

import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;

/**
 * Contem as regras para a analise sintatica
 * @author nathy
 */
public class RegraElementosGerais extends Regra {


    protected static Regra instancia;
     protected static String estrutura ="<elementos_gerais> ::= <op_incremento> | <elemento_variavel> | <elemento_args>";

    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraElementosGerais() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraElementosGerais getInstance() {
        if (instancia == null) {
            instancia = new RegraElementosGerais();
        }
        return (RegraElementosGerais) instancia;
    }

    /**
     * Realiza analise sintatica
     * @param listaTokens - Tokens do codigo
     * @return - Arvore sintatica
     * @throws Exception
     */
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{
    NoArvore naoterminalElemento = new NoArvore("<elementos_gerais>", false);
    NoArvore elemento = reconhecerNaoTerminal(listaTokens,RegraOpIncremento.getInstance());
    if(elemento!= null) naoterminalElemento.adicionaFilho(elemento);
    else {
      elemento = reconhecerNaoTerminal(listaTokens,RegraElementoVariavel.getInstance());
      if(elemento!= null) naoterminalElemento.adicionaFilho(elemento);
      else {
        elemento = reconhecerNaoTerminal(listaTokens,RegraElementoArgs.getInstance());
        if(elemento!= null) naoterminalElemento.adicionaFilho(elemento);
        else{ }//ERRO
      }
    }
    return naoterminalElemento;
    }
    

    @Override
    protected void setPrimeiro() {
        //P<elementos_gerais>  = P<op_incremento> U P<elemento_variavel> U P<elemento_args>
       //this.primeiro = getUniao(RegraOpIncremento.getInstance().getPrimeiro(), RegraElementoVariavel.getInstance().getPrimeiro());
       //this.primeiro = getUniao(this.primeiro, RegraElementoArgs.getInstance().getPrimeiro());
   /*   P <elementos_gerais>  = P<op_incremento> U P<elemento_variavel>  U P<elemento_args>
        -> {'++', '--'} U {e, "[" , "." U "->""} U "("*/
        this.primeiro.add("++");
        this.primeiro.add("--");
        this.primeiro.add("e");
        this.primeiro.add("[");
        this.primeiro.add(".");
        this.primeiro.add("->");
        this.primeiro.add("(");
    }

    @Override
    protected void setSeguinte() {
        //S<elementos_gerais>   = S<unario_posfixa>
        //this.seguinte = RegraUnarioPosfixa.getInstance().getSeguinte();
        seguinte.add("(");
        seguinte.add("{");
        seguinte.add("identificador");
        seguinte.add("numeroInteiro");
        seguinte.add("numeroFlutuante");
        seguinte.add("charconst");
        seguinte.add("++");
        seguinte.add("--");
        seguinte.add("&");
        seguinte.add("*");
        seguinte.add("+");
        seguinte.add("-");
        seguinte.add("<");
        seguinte.add("<=");
        seguinte.add(">");
        seguinte.add(">=");
        seguinte.add("==");
        seguinte.add("!=");
        seguinte.add("&&");
        seguinte.add(";");
        seguinte.add(",");
        seguinte.add("}");
        seguinte.add(")");
    }


 


}
